<?php
declare(strict_types=1);

namespace Zyucv7\Core\Autoloader;

use Zyucv7\Core\Autoloader\IFinder;


/**
 * PSR-4 规范的查找器
 */
class Psr4Finder implements IFinder
{
    /**
     * 命名空间前缀 => 基础目录的映射
     * @var array<string, array<string>>
     */
    private array $prefixes = [];

    /**
     * 添加一个命名空间映射
     *
     * @param string $prefix 命名空间前缀，如 'MyApp\'
     * @param string $baseDir 对应的基础目录，必须是绝对路径，如 '/path/to/project/src/'
     * @return void
     */
    public function addNamespace(string $prefix, string $baseDir): void
    {
        // 规范化命名空间前缀，确保以'\'结尾
        $prefix = trim($prefix, '\\') . '\\';
        // 规范化基础目录，确保以'/'结尾
        $baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR) . '/';
        
        $this->prefixes[$prefix][] = $baseDir;
    }

    public function findFile(string $className): ?string
    {
        // 遍历所有注册的命名空间前缀
        foreach ($this->prefixes as $prefix => $baseDirs) {
            // 检查类名是否以此前缀开头
            if (strpos($className, $prefix) === 0) {
                // 获取相对类名
                $relativeClass = substr($className, strlen($prefix));
                // 将相对类名中的命名空间分隔符替换为目录分隔符
                $file = str_replace('\\', DIRECTORY_SEPARATOR, $relativeClass) . '.php';

                // 遍历该前缀对应的所有基础目录
                foreach ($baseDirs as $baseDir) {
                    $filePath = $baseDir . $file;
                    if (file_exists($filePath)) {
                        return $filePath;
                    }
                }
            }
        }

        return null;
    }
}
